﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Mvc;
using Storytelling.Entidades;
using Storytelling.Modelos;
using Storytelling.Negocio;
using Storytelling.Utils;
using System.Linq;
using Storytelling.Entidades.VTR;
using Storytelling.Modelos.VTR;
using Storytelling.Negocio.Excecoes;
using System.Web.Routing;

namespace Storytelling.Controllers
{
    public class PersonagemController : BaseCrudController<Humano, HumanoFormModel>
    {
        protected override IServico<Humano, HumanoFormModel> Servico
        {
            get { return Servicos.Humano; }
        }

        protected override void EscolherCarregamento(Carga<Humano> carga, TipoCarregamento tipo)
        {
            carga.Carregar(ent => ent.Cronica);

            switch (tipo)
            {
                case TipoCarregamento.Unico:
                    carga.Carregar(ent => ent.Especializacoes).Carregar(ent => ent.Especializacao);
                    carga.Carregar(ent => ent.Vantagens).Carregar(ent => ent.Vantagem);
                    carga.Carregar(ent => ent.Desvantagens).Carregar(ent => ent.Desvantagem);
                    carga.Carregar(ent => ent.Armas).Carregar(ent => ent.Arma);
                    carga.Carregar(ent => ent.Itens).Carregar(ent => ent.Item);
                    carga.Carregar(ent => ent.Jogador);
                    break;
                case TipoCarregamento.Varios:
                    carga.Carregar(ent => ent.Jogador);
                    break;
            }
        }

        public override ActionResult Form(long? id)
        {
            bool evoluir = id.HasValue && Servico.BloquearOperacao(id.Value, User.Identity.Name);

            if (evoluir && Servicos.Humano.BloquearJogador(id.Value, User.Identity.Name))
            {
                return RedirectToAction("Index");
            }

            ViewBag.Evoluir = evoluir;
            return base.Form(id);
        }

        public override ActionResult Form(HumanoFormModel model)
        {
            if (model.Id.HasValue && model.Id.Value > 0 && Servico.BloquearOperacao(model.Id.Value, User.Identity.Name))
            {
                return RedirectToAction("Index");
            }

            model.Jogador = User.Identity.Name;
            return base.Form(model);
        }

        [AutorizarNarrador]
        public override ActionResult Excluir(long? id)
        {
            if (id.HasValue && Servico.BloquearOperacao(id.Value, User.Identity.Name))
            {
                return RedirectToAction("Index");
            }

            return base.Excluir(id);
        }

        [Authorize]
        public ActionResult Evoluir(EvolucaoModel model)
        {
            try
            {
                Servicos.Humano.Evoluir(model);
            }
            catch (StorytellingException ex)
            {
                MensagemExcecao = ex.Message;
            }

            return RedirectToAction("Form", new RouteValueDictionary(
                new { controller = "Personagem", action = "Form", id = model.Id }));
        }

        [Authorize]
        public ActionResult Visualizar(long? id)
        {
            if (id.HasValue && !Servicos.Humano.BloquearJogador(id.Value, User.Identity.Name) 
                || !Servico.BloquearOperacao(id.Value, User.Identity.Name))
            {
                Carga<Humano> carga = new Carga<Humano>();
                EscolherCarregamento(carga, TipoCarregamento.Unico);
                Humano humano = Servicos.Humano.Visualizar(id.Value, carga);

                Response.Clear();
                Response.AddHeader("content-disposition",
                    string.Format("attachment;filename={0}_{1:dd-MM-yyyy-hh-mm}", humano.Nome, DateTime.Now));
                Response.Charset = "";
                Response.Cache.SetCacheability(HttpCacheability.NoCache);
                Response.ContentEncoding = Encoding.UTF8;
                Response.ContentType = "application/vnd.ms-excel";

                if (humano is Vampiro)
                {
                    return View("VisualizarVampiro", (Vampiro)humano);
                }

                return View(humano);
            }

            return RedirectToAction("Index");
        }

        [Authorize]
        public ActionResult Vampiro(long? id)
        {
            bool evoluir = id.HasValue && Servicos.Humano.BloquearOperacaoExtensor(id.Value, User.Identity.Name);

            if (evoluir && Servicos.Humano.BloquearJogador(id.Value, User.Identity.Name))
            {
                return RedirectToAction("Index");
            }

            ViewBag.Evoluir = evoluir;

            VampiroFormModel model = new VampiroFormModel();
            Servicos.Vampiro.Consultar(model, id.Value);
            return View(model);
        }

        [HttpPost]
        [Authorize]
        public virtual ActionResult Vampiro(VampiroFormModel model)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    Servicos.Vampiro.Salvar(model);
                    return RedirectToAction("Index");
                }
            }
            catch (StorytellingException ex)
            {
                MensagemExcecao = ex.Message;
            }

            return View(model);
        }

        [Authorize]
        public JsonResult CronicaPersonagens(long? id)
        {
            FiltrarModel<Humano> model = new FiltrarModel<Humano>();

            EscolherCarregamento(model.Carga, TipoCarregamento.Autocompletar);

            if (id.HasValue)
            {
                model.Exemplo.CronicaId = id.Value;
            }

            Servico.Filtrar(model);
            return Json(model.Colecao.OrderBy(ent => ent.Nome).Select(ent => new { ent.Id, ent.Nome }));
        }

        [Authorize]
        public JsonResult MeusPersonagens(string nome)
        {
            FiltrarModel<Humano> model = new FiltrarModel<Humano>();
            model.Inativados = false;
            model.Exemplo.Nome = nome;

            Usuario usuario = Session["Usuario"] as Usuario;

            if (usuario != null)
            {
                model.Exemplo.JogadorId = usuario.Id;
            }
            else
            {
                return Json(model.Colecao.Select(ent => new { ent.Id, ent.Nome }));
            }

            EscolherCarregamento(model.Carga, TipoCarregamento.Autocompletar);
            Servico.Filtrar(model);
            return Json(model.Colecao.Select(ent => new { ent.Id, ent.Nome }));
        }

        [Authorize]
        public JsonResult MeusEquipamentos(long? id, string nome)
        {
            if (!id.HasValue || id.Value == 0)
            {
                return Json(new List<Arma>());
            }

            nome = nome.ToUpperInvariant();
            Carga<Humano> carga = new Carga<Humano>();
            EscolherCarregamento(carga, TipoCarregamento.Unico);
            Humano humano = Servico.Consultar(id.Value, carga);
            return Json(humano.Armas.Where(ent => ent.Arma.Nome.ToUpperInvariant().Contains(nome)).Select(ent => new { ent.Id, ent.Arma.Nome }));
        }
    }
}
